Skip to content

[Repo Assist] perf: avoid ToCharArray allocations in TextConversions, HtmlParser, HtmlCssSelectors, HtmlOperations#1735

Draft
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/perf-avoid-tochararray-allocs-2026-04-09-b73ef14a269e58dc
Draft

[Repo Assist] perf: avoid ToCharArray allocations in TextConversions, HtmlParser, HtmlCssSelectors, HtmlOperations#1735
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/perf-avoid-tochararray-allocs-2026-04-09-b73ef14a269e58dc

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Apr 9, 2026

🤖 This is an automated pull request from Repo Assist, an AI assistant for this repository.

Continues the series of allocation-reduction PRs (#1725, #1728, #1729, #1733) by eliminating remaining ToCharArray() calls that create unnecessary intermediate allocations.

Changes

TextConversions.RemoveAdorners (hotpath)

The slow path for removing currency/percentage adorners used ToCharArray() |> Array.filter, allocating two char arrays before creating the final string. Replaced with a StringBuilder loop that iterates the string directly (string is IEnumerable<char> in .NET):

// Before: two intermediate char[] allocations
String(value.ToCharArray() |> Array.filter (...))

// After: single StringBuilder, pre-allocated to value.Length
let sb = System.Text.StringBuilder(value.Length)
for c in value do
    if not (...) then sb.Append(c) |> ignore
sb.ToString()

This is called on every number/date parse attempt across CSV, JSON, and XML type inference.

HtmlParser — reversed-tag detection

The malformed-end-tag check (<li></il>) reversed a string via ToCharArray() |> Array.rev. Replaced with Array.init using direct index arithmetic — avoids ToCharArray() and a second array for the reversed result.

HtmlCssSelectors — three sites

  • StartsWith active pattern: removed ToCharArray() and compared the char list directly against the string via Seq.compareWith (strings are IEnumerable<char>)
  • TokenStr active pattern: s.ToCharArray() |> Array.toListList.ofSeq s
  • Tokenize method: cssSelector.ToCharArray() |> Array.toListList.ofSeq cssSelector

HtmlOperations — CSS attribute selector

v.ToCharArray() |> Seq.skipWhile ...v |> Seq.skipWhile ... (direct string enumeration)

Test Status

  • dotnet test tests/FSharp.Data.Core.Tests/2909 passed, 0 failed
  • ✅ Formatted with Fantomas 7.0.1

Generated by Repo Assist

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@7ee2b60744abf71b985bead4599640f165edcd93

…tmlCssSelectors, HtmlOperations

- TextConversions.RemoveAdorners: replace ToCharArray()+Array.filter with a
  StringBuilder loop; avoids two intermediate char[] allocations (ToCharArray
  result + filtered result) on the hot path for every number/date parse attempt
- HtmlParser: replace ToCharArray()|>Array.rev string reversal with Array.init
  using direct index arithmetic; avoids ToCharArray allocation for malformed
  end-tag detection (e.g. <li></il>)
- HtmlCssSelectors.StartsWith: remove ToCharArray(); compare list against string
  directly via Seq.compareWith (string is IEnumerable<char>)
- HtmlCssSelectors.TokenStr: replace ToCharArray()|>Array.toList with List.ofSeq
- HtmlCssSelectors.Tokenize: replace ToCharArray()|>Array.toList with List.ofSeq
- HtmlOperations AttributeContainsPrefix: remove ToCharArray() before Seq.skipWhile
  since string is already IEnumerable<char>

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants